Taking Screenshots in Selenium
Taking Screenshots is an important feature in Selenium automation testing that allows testers to capture the current state of a web page or browser when a test is executed. Screenshots are especially useful when a test fails because they provide visual evidence of what was displayed in the browser at the time of execution.
In Selenium automation frameworks, screenshots can be captured during normal test execution, after specific actions, when an assertion fails, or automatically whenever a test case fails. Screenshots are commonly integrated with TestNG, Page Object Model (POM), listeners, reporting tools, and CI/CD pipelines.
Screenshots are particularly useful for debugging login failures, incorrect page navigation, missing elements, unexpected pop-ups, validation failures, synchronization issues, and UI defects.
Course Resource: Selenium Training | Register for Course Demo
1. What is a Screenshot in Selenium?
A screenshot is an image capture of the browser or web page at a particular point during test execution. Selenium WebDriver provides the TakesScreenshot interface for capturing screenshots.
When a Selenium test fails, a screenshot can help identify what the browser looked like at the exact time of failure.
Test Execution
|
v
Browser Interaction
|
v
Test Failure / Important Step
|
v
Capture Screenshot
|
v
Save Image
|
v
Attach to Report / Log
2. Why are Screenshots Important?
Screenshots provide visual evidence of the application state during automated testing. They make debugging easier because a tester can see what was displayed in the browser without manually reproducing the failure.
- Helps debug failed test cases.
- Provides visual evidence of test execution.
- Helps identify UI defects.
- Makes automation reports more informative.
- Helps investigate unexpected browser states.
- Useful for failed login scenarios.
- Helps identify incorrect navigation.
- Useful for regression testing.
- Can be attached to TestNG reports.
- Can be integrated with CI/CD pipelines.
- Helps developers reproduce automation failures.
- Provides historical evidence of failures.
3. Selenium TakesScreenshot Interface
Selenium provides the TakesScreenshot interface for capturing screenshots.
The interface is commonly used with the WebDriver instance by type casting the driver to TakesScreenshot.
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.OutputType;
TakesScreenshot screenshot =
(TakesScreenshot) driver;
The screenshot can then be obtained using the getScreenshotAs() method.
4. Basic Screenshot Syntax
File source =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
Here:
- driver represents the WebDriver instance.
- TakesScreenshot provides screenshot functionality.
- getScreenshotAs() captures the screenshot.
- OutputType.FILE requests the screenshot as a file.
5. Complete Basic Screenshot Example
import java.io.File;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class ScreenshotExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
File source =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
System.out.println(
"Screenshot captured: " + source.getAbsolutePath()
);
driver.quit();
}
}
6. Saving a Screenshot to a Specific Location
After capturing a screenshot as a file, it can be copied to a desired destination.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
File source =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
Path destination =
Path.of("screenshots/homepage.png");
Files.createDirectories(destination.getParent());
Files.copy(
source.toPath(),
destination,
StandardCopyOption.REPLACE_EXISTING
);
This approach uses the Java NIO API to create the screenshot directory and save the captured image.
7. Screenshot Using OutputType.FILE
OutputType.FILE returns the screenshot as a temporary file.
File screenshot =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
This output is useful when the screenshot needs to be copied or moved to a permanent location.
8. Screenshot Using OutputType.BYTES
Selenium can also return screenshot data as bytes. This is useful when a framework wants to process or attach the screenshot without first creating a file manually.
byte[] screenshot =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BYTES);
Bytes can be useful when integrating screenshots with reporting systems, databases, APIs, or custom logging mechanisms.
9. Screenshot Using OutputType.BASE64
Selenium can also return the screenshot as a Base64 encoded string.
String screenshot =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BASE64);
Base64 screenshots can be useful when a reporting framework accepts image data as a string.
10. Screenshot Output Types
| Output Type | Result | Common Usage |
| OutputType.FILE | Temporary File | Save screenshot to disk |
| OutputType.BYTES | byte[] | Programmatic processing |
| OutputType.BASE64 | Base64 String | Reports and custom integrations |
11. Creating a Reusable Screenshot Method
In a real automation framework, screenshot code should not be duplicated in every test method. A reusable utility method can be created.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
public class ScreenshotUtil {
public static String captureScreenshot(
WebDriver driver,
String fileName) throws IOException {
File source =
((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
Path destination =
Path.of("screenshots", fileName + ".png");
Files.createDirectories(destination.getParent());
Files.copy(
source.toPath(),
destination,
StandardCopyOption.REPLACE_EXISTING
);
return destination.toString();
}
}
12. Using Screenshot Utility in a Test
String path =
ScreenshotUtil.captureScreenshot(
driver,
"login-page"
);
System.out.println("Screenshot: " + path);
The test class only needs to call the utility method instead of repeating the complete screenshot implementation.
13. Taking a Screenshot After Opening a Page
driver.get("https://example.com");
ScreenshotUtil.captureScreenshot(
driver,
"homepage"
);
This can be useful when visual evidence is required after navigation.
14. Taking a Screenshot After Login
driver.findElement(By.id("username"))
.sendKeys("admin");
driver.findElement(By.id("password"))
.sendKeys("password");
driver.findElement(By.id("loginButton"))
.click();
ScreenshotUtil.captureScreenshot(
driver,
"after-login"
);
15. Taking a Screenshot Before an Important Action
Screenshots can be captured before important operations such as submitting a form, deleting a record, making a booking, or placing an order.
ScreenshotUtil.captureScreenshot(
driver,
"before-submit"
);
driver.findElement(By.id("submit"))
.click();
16. Taking a Screenshot After an Important Action
driver.findElement(By.id("submit"))
.click();
ScreenshotUtil.captureScreenshot(
driver,
"after-submit"
);
Capturing screenshots both before and after an action can provide useful evidence for important workflows.
17. Taking a Screenshot When a Test Fails
One of the most valuable uses of screenshots is automatic capture when a test fails.
try {
// Test steps
driver.findElement(By.id("username"))
.sendKeys("admin");
driver.findElement(By.id("loginButton"))
.click();
} catch (Exception e) {
ScreenshotUtil.captureScreenshot(
driver,
"login-failure"
);
throw e;
}
In a production framework, TestNG listeners are generally preferred for automatically capturing screenshots for failed tests.
18. Screenshot with TestNG
TestNG is commonly used with Selenium to organize and execute automated test cases. Screenshots can be integrated with TestNG test lifecycle methods.
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class LoginTest {
WebDriver driver;
@BeforeMethod
public void setup() {
driver = new ChromeDriver();
}
@Test
public void loginTest() {
driver.get("https://example.com/login");
// Test steps
}
@AfterMethod
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
19. Using ITestResult for Failed Test Screenshots
TestNG's ITestResult can be used in configuration methods to determine whether a test passed or failed.
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
@AfterMethod
public void captureFailure(ITestResult result) throws IOException {
if (result.getStatus() == ITestResult.FAILURE) {
ScreenshotUtil.captureScreenshot(
driver,
result.getName()
);
}
}
This approach allows screenshots to be captured automatically after failed test methods.
20. Screenshot Using TestNG Listener
A TestNG listener is a powerful way to centralize screenshot capture logic. Instead of adding screenshot code to every test, the listener can capture a screenshot whenever a test fails.
import org.testng.ITestListener;
import org.testng.ITestResult;
public class TestListener implements ITestListener {
@Override
public void onTestFailure(ITestResult result) {
System.out.println(
"Test Failed: " + result.getName()
);
// Capture screenshot here
}
}
21. WebDriver Access in a TestNG Listener
The listener needs access to the WebDriver instance used by the failing test. A common framework design is to store the driver in a thread-safe driver manager or retrieve it from the test instance.
Object instance = result.getInstance();
System.out.println(
"Failed Test Class: "
+ instance.getClass().getSimpleName()
);
The exact implementation depends on the architecture of the automation framework.
22. Complete TestNG Listener Screenshot Example
import java.io.IOException;
import org.openqa.selenium.WebDriver;
import org.testng.ITestListener;
import org.testng.ITestResult;
public class TestListener implements ITestListener {
@Override
public void onTestFailure(ITestResult result) {
Object testObject = result.getInstance();
if (testObject instanceof BaseTest) {
WebDriver driver =
((BaseTest) testObject).getDriver();
try {
ScreenshotUtil.captureScreenshot(
driver,
result.getMethod()
.getMethodName()
);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
23. Base Test Class for Screenshot Framework
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class BaseTest {
protected WebDriver driver;
public void setupDriver() {
driver = new ChromeDriver();
}
public WebDriver getDriver() {
return driver;
}
}
A base test class can provide a consistent WebDriver lifecycle for test classes and utilities.
24. Registering a TestNG Listener
A listener can be registered using the @Listeners annotation.
import org.testng.annotations.Listeners;
@Listeners(TestListener.class)
public class LoginTest extends BaseTest {
// Test methods
}
After registration, the listener can receive TestNG lifecycle events such as test failures.
25. Taking Screenshots with Page Object Model
In a Page Object Model framework, screenshot functionality should generally remain in a utility or framework layer rather than being duplicated inside every page class.
public class LoginPage {
private WebDriver driver;
private By username =
By.id("username");
private By password =
By.id("password");
private By loginButton =
By.id("loginButton");
public LoginPage(WebDriver driver) {
this.driver = driver;
}
public void login(
String user,
String pass) {
driver.findElement(username)
.sendKeys(user);
driver.findElement(password)
.sendKeys(pass);
driver.findElement(loginButton)
.click();
}
}
The test layer can call the screenshot utility whenever visual evidence is required.
26. Screenshot Utility with Timestamp
Using timestamps in screenshot names prevents files from being overwritten when the same test is executed multiple times.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
String timestamp =
LocalDateTime.now()
.format(
DateTimeFormatter.ofPattern(
"yyyyMMdd_HHmmss"
)
);
String fileName =
"LoginTest_" + timestamp;
A generated filename may look like:
LoginTest_20261001_131500.png
27. Screenshot with Test Name and Timestamp
String testName =
result.getMethod().getMethodName();
String timestamp =
LocalDateTime.now()
.format(
DateTimeFormatter.ofPattern(
"yyyyMMdd_HHmmss"
)
);
String fileName =
testName + "_" + timestamp;
This makes screenshot files easier to identify in large test suites.
28. Organizing Screenshot Folders
A clean automation project should store screenshots in a dedicated directory.
project
|
|-- src
| |-- test
| |-- java
| |-- tests
| |-- pages
| |-- utilities
|
|-- screenshots
| |-- passed
| |-- failed
| |-- evidence
|
|-- reports
|
|-- pom.xml
Separating screenshots from source code keeps the automation project easier to maintain.
29. Failed Screenshot Folder
A framework can maintain a separate folder for screenshots generated from failed tests.
screenshots/
|
|-- failed/
| |-- LoginTest_20261001_131500.png
| |-- SearchTest_20261001_131530.png
| |-- CheckoutTest_20261001_131600.png
|
|-- passed/
|
|-- evidence/
30. Screenshot Naming Convention
Meaningful screenshot names make debugging easier.
| Screenshot Name | Purpose |
| login_failure.png | Login failure evidence |
| homepage.png | Homepage state |
| search_results.png | Search results evidence |
| checkout_failure.png | Checkout failure evidence |
| LoginTest_20261001_131500.png | Timestamped test screenshot |
31. Taking Screenshots for Specific Web Elements
Modern Selenium versions support taking screenshots of individual WebElements.
WebElement logo =
driver.findElement(
By.id("logo")
);
File screenshot =
logo.getScreenshotAs(
OutputType.FILE
);
This is useful when only a particular UI component needs to be captured.
32. Element Screenshot Example
WebElement loginForm =
driver.findElement(
By.id("loginForm")
);
File screenshot =
loginForm.getScreenshotAs(
OutputType.FILE
);
Element-level screenshots are useful for capturing forms, cards, buttons, tables, banners, and other individual components.
33. Full Page Screenshot vs Viewport Screenshot
A standard WebDriver screenshot generally captures the browser's current visible viewport. Full-page screenshot behavior can depend on the browser and driver implementation.
| Type | Description |
| Viewport Screenshot | Captures the currently visible browser area |
| Element Screenshot | Captures a specific WebElement |
| Full Page Screenshot | Captures the entire page where supported by the browser/driver |
34. Full Page Screenshot Considerations
When a test requires the entire web page rather than only the visible viewport, the framework should use a screenshot approach supported by the selected browser and Selenium version.
For example, Selenium's screenshot capabilities and browser-specific support can be evaluated when implementing full-page evidence collection.
35. Screenshot After Explicit Wait
Capturing a screenshot before an element has finished loading can produce misleading evidence. Explicit waits can be used before taking screenshots of dynamic content.
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement dashboard =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("dashboard")
)
);
ScreenshotUtil.captureScreenshot(
driver,
"dashboard-loaded"
);
36. Screenshot for Validation Failure
try {
Assert.assertTrue(
driver.getTitle()
.contains("Dashboard")
);
} catch (AssertionError e) {
ScreenshotUtil.captureScreenshot(
driver,
"title-validation-failure"
);
throw e;
}
In larger TestNG frameworks, listener-based failure capture is generally preferable to manually wrapping every assertion.
37. Screenshot and Assertions
Screenshots can provide evidence when an assertion fails.
String actualTitle =
driver.getTitle();
String expectedTitle =
"Dashboard";
Assert.assertEquals(
actualTitle,
expectedTitle
);
If the assertion fails, a TestNG listener can automatically capture the browser state.
38. Screenshot and Test Reports
Screenshots become significantly more useful when attached to automated test reports. A report can show the test name, status, error message, stack trace, and screenshot associated with the failure.
Test Case
|
+-- Status
|
+-- Error Message
|
+-- Stack Trace
|
+-- Screenshot
|
+-- Execution Time
This creates a more complete picture of the test result.
39. Screenshot with ExtentReports
ExtentReports can be integrated with Selenium and TestNG to create HTML-based test reports. Screenshots can be attached to report entries when tests fail.
test.fail(
"Login test failed"
);
A framework can capture the screenshot path and attach it to the corresponding report entry using the reporting library's supported APIs.
40. Screenshot with Allure Reports
Allure is another reporting solution that can display screenshots and other test artifacts.
Allure.addAttachment(
"Screenshot",
"image/png",
new ByteArrayInputStream(
screenshotBytes
),
"png"
);
The exact Allure integration depends on the project dependencies and reporting setup.
41. Screenshot on Test Failure Architecture
TestNG Test
|
v
Test Passes? ---- Yes ----> Continue
|
No
|
v
TestNG Listener
|
v
Get WebDriver
|
v
Capture Screenshot
|
v
Save Screenshot
|
v
Attach to Report
|
v
Test Result
42. Screenshot During Login Testing
Login testing is one of the most common scenarios for screenshot capture.
Open Login Page
|
v
Enter Username
|
v
Enter Password
|
v
Click Login
|
v
Validate Dashboard
|
+---- Pass ----> Optional Evidence
|
+---- Fail ----> Capture Screenshot
43. Screenshot During E-Commerce Testing
Screenshots are useful at important checkpoints in e-commerce workflows.
- Product search.
- Product details.
- Product added to cart.
- Cart validation.
- Checkout page.
- Address validation.
- Payment page.
- Order confirmation.
- Failed checkout.
44. Screenshot During Form Testing
Open Registration Form
|
v
Enter User Information
|
v
Submit Form
|
v
Validate Success / Error
|
v
Capture Evidence
For validation testing, screenshots can help confirm whether the expected validation messages appeared.
45. Screenshot During Regression Testing
Regression test suites may execute hundreds or thousands of automated tests. Automatically capturing screenshots only for failures helps control storage usage while still providing evidence for failed cases.
Regression Suite
|
v
Test 1 ---- PASS
Test 2 ---- PASS
Test 3 ---- FAIL ---> Screenshot
Test 4 ---- PASS
Test 5 ---- FAIL ---> Screenshot
|
v
Generate Report
46. Screenshot in Parallel Execution
When tests execute in parallel, screenshot filenames must be unique. Otherwise, multiple threads may overwrite the same file.
Thread 1
|
+-- LoginTest_Thread1.png
Thread 2
|
+-- LoginTest_Thread2.png
Thread 3
|
+-- LoginTest_Thread3.png
Including test name, timestamp, thread ID, or a unique identifier in the filename can help prevent collisions.
47. Thread-Safe Screenshot Naming
String threadId =
String.valueOf(
Thread.currentThread().getId()
);
String fileName =
testName
+ "_thread_"
+ threadId
+ "_"
+ timestamp;
This is particularly useful when Data Providers or TestNG parallel execution are enabled.
48. Screenshot with Data-Driven Testing
When a Data Provider executes the same test with multiple data sets, screenshots should identify the data set when possible.
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"admin", "valid"},
{"manager", "valid"},
{"invalid", "invalid"}
};
}
@Test(dataProvider = "loginData")
public void loginTest(
String username,
String scenario) {
// Test execution
}
A screenshot filename can include the scenario name without exposing sensitive credentials.
49. Screenshot and Sensitive Information
Screenshots can accidentally contain sensitive information such as passwords, access tokens, customer information, payment details, or personal data.
Automation frameworks should therefore avoid capturing sensitive information unnecessarily and should apply appropriate access controls to screenshot artifacts.
- Do not intentionally expose passwords in screenshots.
- Avoid capturing payment information unless required.
- Mask sensitive fields where possible.
- Protect report files containing screenshots.
- Do not publish sensitive screenshots to public repositories.
- Apply appropriate retention policies.
50. Screenshot Utility Best Practices
- Keep screenshot logic in a reusable utility.
- Use meaningful filenames.
- Include timestamps for repeated executions.
- Include test names where appropriate.
- Capture screenshots automatically on failures.
- Attach failure screenshots to reports.
- Store screenshots in dedicated directories.
- Clean old screenshots periodically.
- Avoid exposing sensitive information.
- Use unique filenames during parallel execution.
- Keep screenshot code separate from page interaction logic.
51. Common Mistakes While Taking Screenshots
- Forgetting to cast WebDriver to TakesScreenshot.
- Using an invalid screenshot path.
- Not creating the screenshot directory.
- Overwriting screenshots with identical filenames.
- Capturing screenshots before dynamic content is loaded.
- Not closing the browser after execution.
- Capturing screenshots for every step unnecessarily.
- Sharing screenshot filenames between parallel threads.
- Not attaching screenshots to reports.
- Storing sensitive information in screenshots.
- Writing duplicate screenshot code in every test class.
52. Screenshot Path Management
Hard-coded absolute paths can cause problems when tests run on another machine or CI server.
Instead of:
C:\Users\Tester\Desktop\screenshots
Prefer project-relative or configurable paths.
Path screenshotDirectory =
Path.of("screenshots", "failed");
Files.createDirectories(
screenshotDirectory
);
53. Screenshot Utility with Automatic Directory Creation
public static String capture(
WebDriver driver,
String fileName) throws IOException {
Path directory =
Path.of("screenshots");
Files.createDirectories(directory);
Path destination =
directory.resolve(
fileName + ".png"
);
File source =
((TakesScreenshot) driver)
.getScreenshotAs(
OutputType.FILE
);
Files.copy(
source.toPath(),
destination,
StandardCopyOption.REPLACE_EXISTING
);
return destination.toString();
}
54. Screenshot Utility with Unique Filename
public static String generateFileName(
String testName) {
String timestamp =
LocalDateTime.now()
.format(
DateTimeFormatter.ofPattern(
"yyyyMMdd_HHmmss_SSS"
)
);
String thread =
String.valueOf(
Thread.currentThread().getId()
);
return testName
+ "_"
+ timestamp
+ "_thread_"
+ thread
+ ".png";
}
55. Screenshot and CI/CD
Screenshots are especially valuable in CI/CD because automated tests may execute on remote servers where a tester cannot directly observe the browser.
Developer Commit
|
v
CI/CD Pipeline
|
v
Build Application
|
v
Run Selenium Tests
|
v
Test Failure
|
v
Capture Screenshot
|
v
Store Artifact
|
v
Generate Report
|
v
Developer Investigates Failure
56. Screenshot Artifacts in CI
When tests run in CI environments, screenshot files can be preserved as build artifacts depending on the CI platform configuration.
This allows developers and testers to inspect failed screenshots after the automated pipeline has completed.
57. Screenshot and Headless Browser Testing
Screenshots are also useful when Selenium tests execute in headless mode. Since there may be no visible browser window on the test machine, screenshots provide visual evidence of the browser state.
ChromeOptions options =
new ChromeOptions();
options.addArguments("--headless=new");
WebDriver driver =
new ChromeDriver(options);
Headless execution is frequently used in CI/CD environments.
58. Screenshot and Browser Size
Browser window size can affect screenshots and responsive layouts. For consistent evidence, the framework can use a controlled window size.
driver.manage()
.window()
.setSize(
new Dimension(1440, 900)
);
This can make screenshots more consistent across executions.
59. Screenshot for Responsive Testing
Screenshots can help validate responsive layouts across different viewport sizes.
| Viewport | Example Purpose |
| 375 × 812 | Mobile layout |
| 768 × 1024 | Tablet layout |
| 1366 × 768 | Desktop layout |
| 1440 × 900 | Large desktop layout |
60. Screenshot and Debugging Workflow
Test Failure
|
v
Open Test Report
|
v
Read Error Message
|
v
Open Screenshot
|
v
Observe Browser State
|
v
Identify UI Problem
|
v
Reproduce Issue
|
v
Fix Automation/Application
|
v
Run Test Again
61. Complete Practical Screenshot Utility
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
public class ScreenshotUtil {
public static String captureScreenshot(
WebDriver driver,
String testName) throws IOException {
String timestamp =
LocalDateTime.now()
.format(
DateTimeFormatter.ofPattern(
"yyyyMMdd_HHmmss_SSS"
)
);
String threadId =
String.valueOf(
Thread.currentThread().getId()
);
String fileName =
testName
+ "_"
+ timestamp
+ "_thread_"
+ threadId
+ ".png";
Path directory =
Path.of("screenshots", "failed");
Files.createDirectories(directory);
File source =
((TakesScreenshot) driver)
.getScreenshotAs(
OutputType.FILE
);
Path destination =
directory.resolve(fileName);
Files.copy(
source.toPath(),
destination,
StandardCopyOption.REPLACE_EXISTING
);
return destination.toString();
}
}
62. Complete Practical TestNG Screenshot Example
import java.io.IOException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class LoginTest {
private WebDriver driver;
@BeforeMethod
public void setup() {
driver = new ChromeDriver();
driver.manage()
.window()
.maximize();
driver.get(
"https://example.com/login"
);
}
@Test
public void loginTest() {
driver.findElement(
By.id("username")
).sendKeys("admin");
driver.findElement(
By.id("password")
).sendKeys("password");
driver.findElement(
By.id("loginButton")
).click();
}
@AfterMethod
public void tearDown(
ITestResult result) throws IOException {
if (result.getStatus()
== ITestResult.FAILURE) {
ScreenshotUtil.captureScreenshot(
driver,
result.getMethod()
.getMethodName()
);
}
if (driver != null) {
driver.quit();
}
}
}
63. Complete Screenshot Framework Architecture
Selenium Test
|
v
TestNG Test
|
+---------+---------+
| |
PASS FAIL
| |
v v
Test Result Test Listener
|
v
Get WebDriver
|
v
Screenshot Utility
|
v
Save PNG File
|
+------------+------------+
| |
v v
Reports CI Artifact
64. Practical Project Structure
selenium-project
|
|-- src
| |-- test
| |-- java
| |-- tests
| | |-- LoginTest.java
| | |-- SearchTest.java
| | |-- CheckoutTest.java
| |
| |-- pages
| | |-- LoginPage.java
| | |-- SearchPage.java
| | |-- CheckoutPage.java
| |
| |-- utilities
| |-- ScreenshotUtil.java
| |-- DriverFactory.java
| |-- ConfigReader.java
| |-- TestListener.java
|
|-- screenshots
| |-- failed
| |-- passed
| |-- evidence
|
|-- reports
|
|-- pom.xml
65. Screenshot Strategy for Automation Frameworks
| Scenario | Screenshot Recommendation |
| Test Passed | Capture only when evidence is required |
| Test Failed | Automatically capture |
| Assertion Failure | Automatically capture |
| Important Workflow | Capture checkpoint evidence when useful |
| Regression Testing | Prefer failure screenshots |
| Parallel Execution | Use unique filenames |
| CI/CD | Store screenshots as build artifacts |
| Reporting | Attach screenshots to failed tests |
66. Advantages of Taking Screenshots
- Easy Debugging: Visual evidence makes failures easier to understand.
- Failure Analysis: Testers can inspect the application state at failure time.
- Better Reporting: Screenshots make reports more informative.
- Test Evidence: Screenshots can provide evidence for important workflows.
- CI/CD Support: Screenshots are valuable when tests execute remotely.
- Regression Support: Failed regression tests can automatically produce visual evidence.
- UI Validation: Screenshots can help identify visual and layout problems.
- Team Collaboration: Developers can inspect screenshots when investigating automation failures.
67. Limitations of Screenshots
- Large test suites can generate many image files.
- Screenshot storage can increase over time.
- Screenshots do not explain the root cause by themselves.
- Screenshots may contain sensitive information.
- Parallel tests require careful filename management.
- Incorrect timing can result in screenshots of an intermediate state.
- CI environments may require additional artifact configuration.
68. Best Practices for Taking Screenshots
- Capture screenshots automatically when tests fail.
- Use a centralized screenshot utility.
- Use TestNG listeners for framework-level failure capture.
- Use unique and meaningful filenames.
- Include test name and timestamp where useful.
- Include thread information when running tests in parallel.
- Attach screenshots to test reports.
- Store screenshots in dedicated folders.
- Clean old screenshot artifacts regularly.
- Avoid exposing passwords and sensitive information.
- Use waits before capturing screenshots of dynamic content.
- Keep screenshot functionality separate from page object logic.
- Use CI artifact storage for screenshots generated remotely.
- Capture screenshots at important checkpoints rather than unnecessarily after every command.
69. Common Interview Questions on Selenium Screenshots
1. How do you take a screenshot in Selenium?
Selenium provides the TakesScreenshot interface and the getScreenshotAs() method for capturing screenshots.
2. Which interface is used for screenshots?
The TakesScreenshot interface is used.
3. Which method captures a screenshot?
The getScreenshotAs() method captures a screenshot.
4. What is OutputType.FILE?
OutputType.FILE returns the captured screenshot as a temporary file.
5. What is OutputType.BYTES?
OutputType.BYTES returns screenshot data as a byte array.
6. What is OutputType.BASE64?
OutputType.BASE64 returns screenshot data as a Base64 encoded string.
7. Can Selenium capture an individual element?
Yes. WebElement provides screenshot support in Selenium versions that support element screenshots.
8. Why are screenshots useful in automation?
They provide visual evidence of the browser state and help investigate failed test cases.
9. How can screenshots be captured automatically on test failure?
TestNG listeners or configuration methods such as @AfterMethod can be used to trigger screenshot capture after failures.
10. Why are TestNG listeners useful for screenshots?
Listeners centralize failure handling so screenshot code does not need to be repeated in every test method.
11. Can screenshots be attached to reports?
Yes. Reporting frameworks such as ExtentReports and Allure can be integrated with Selenium screenshots.
12. How can screenshots be used in CI/CD?
Screenshots can be stored as build artifacts so developers can inspect failures from automated pipelines.
13. What problem can occur with screenshots during parallel execution?
Multiple test threads may write to the same filename. Unique filenames should therefore be generated.
14. Should screenshots be captured for every Selenium command?
Usually not. Capturing screenshots on failures and at important checkpoints is generally more practical.
15. Can screenshots contain sensitive information?
Yes. Screenshots can contain passwords, personal information, tokens, or other confidential data, so they should be handled securely.
16. Can screenshots be taken in headless mode?
Yes. Screenshots are particularly useful in headless and CI environments because they provide visual evidence without requiring a visible browser window.
17. Why should screenshots use timestamps?
Timestamps help prevent files from being overwritten during repeated test execution.
18. How should screenshot functionality be organized in a framework?
A reusable ScreenshotUtil or similar utility class is commonly used, with TestNG listeners responsible for automatic failure capture.
19. What is the difference between an element screenshot and a browser screenshot?
A browser screenshot captures the current browser viewport, while an element screenshot captures a specific WebElement.
20. What is the most common use of screenshots in Selenium frameworks?
The most common use is automatically capturing screenshots when a test fails and attaching them to the test report.
70. Quick Reference Table
| Concept | Description |
| TakesScreenshot | Selenium interface used for screenshot capture |
| getScreenshotAs() | Captures screenshot data |
| OutputType.FILE | Returns screenshot as a file |
| OutputType.BYTES | Returns screenshot as byte array |
| OutputType.BASE64 | Returns screenshot as Base64 string |
| WebElement Screenshot | Captures an individual web element |
| ITestResult | Provides TestNG test result information |
| ITestListener | Allows framework-level TestNG event handling |
| Screenshot Utility | Centralizes screenshot functionality |
| ExtentReports | Can display screenshot evidence in reports |
| Allure | Can display screenshot attachments in reports |
| CI/CD | Can preserve screenshots as build artifacts |
71. Learning Roadmap for Selenium Screenshots
- Understand Selenium WebDriver.
- Learn the TakesScreenshot interface.
- Understand getScreenshotAs().
- Learn OutputType.FILE.
- Learn OutputType.BYTES and BASE64.
- Create a reusable screenshot utility.
- Use screenshots with TestNG.
- Capture screenshots after failures.
- Learn TestNG listeners.
- Attach screenshots to reports.
- Integrate screenshots with Page Object Model frameworks.
- Handle screenshots during parallel execution.
- Use screenshots in CI/CD pipelines.
- Manage screenshot storage and sensitive information.
72. Practical Exercises
- Create a Selenium test that captures a screenshot after opening a website.
- Create a reusable ScreenshotUtil class.
- Capture a screenshot after successful login.
- Capture a screenshot after a failed login.
- Capture an individual WebElement screenshot.
- Create a TestNG @AfterMethod screenshot implementation.
- Create a TestNG listener that captures screenshots on failure.
- Add timestamps to screenshot filenames.
- Add thread IDs to screenshot filenames.
- Attach screenshots to an HTML test report.
- Store failed screenshots in a dedicated folder.
- Run screenshot-enabled tests in headless mode.
- Integrate screenshot capture with a Page Object Model framework.
- Preserve screenshots as CI/CD build artifacts.
73. Real-World Screenshot Workflow
Test Case Starts
|
v
Open Application
|
v
Perform Test Steps
|
v
Assertion / Validation
|
+------ PASS ------> Test Result
|
+------ FAIL
|
v
TestNG Listener
|
v
Capture Screenshot
|
v
Save PNG File
|
v
Attach to Report
|
v
CI/CD Artifact
|
v
Failure Investigation
74. Summary
Screenshots are an important part of professional Selenium automation frameworks because they provide visual evidence of the browser state during test execution. Selenium supports screenshot capture through the TakesScreenshot interface and the getScreenshotAs() method.
Screenshots can be returned as files, bytes, or Base64 data. They can also be captured for individual WebElements where supported. In a real-world Selenium framework, screenshot functionality is commonly centralized in a reusable utility class.
TestNG listeners and test lifecycle methods can be used to automatically capture screenshots when test cases fail. These screenshots can then be attached to HTML reports or reporting systems such as ExtentReports and Allure.
For scalable automation frameworks, screenshots should be combined with meaningful filenames, timestamps, thread-safe naming, dedicated storage, secure handling of sensitive information, and CI/CD artifact management.
Final Takeaway: Taking screenshots in Selenium is not simply about saving an image. A well-designed screenshot mechanism provides reliable visual evidence, improves debugging, strengthens test reporting, and helps teams investigate failures efficiently, especially in large Selenium, TestNG, POM, and CI/CD automation frameworks.
75. Course Resources
Learn more about Selenium automation testing and related concepts: